'use strict';

const  FS = require('fs'),  Path = require('path');

const  MINE_Type = require('./MIME-Type'),  Utility = require('../libs/utility');



function FolderList(path) {

    return  new Promise(function (resolve, reject) {

        FS.readdir(path,  function (error, data) {

            if ( error )  return  reject( error );

            resolve(data.map(function (file) {
                file = {
                    name:    file,
                    type:    MINE_Type( file ),
                    path:    path + file
                };

                return  Object.assign(file,  FS.statSync( file.path ));
            }));
        });
    });
}

module.exports = function ()  {

    const root_path = Utility.fromCWD('public');

    var file_path = root_path  +  decodeURI( this.url.pathname );

    var file_stat = FS.statSync( file_path );

    if ( file_stat.isDirectory() ) {

        let _FP_ = Path.join(file_path, 'index.html');

        if (! FS.existsSync(_FP_))
            return  FolderList( file_path ).then(function () {

                return  arguments[0].map(function (file) {
                    var _file_ = {
                            name:    file.name,
                            type:    file.type,
                            path:    encodeURI(
                                file.path.replace(root_path, '')
                            ),
                            size:    file.size
                        };

                    for (var key in file)  if (file[key] instanceof Date)
                        _file_[key] = +file[key];

                    return _file_;
                });
            });

        file_path = _FP_;

        file_stat = FS.statSync(_FP_);
    }

    var header = this.request.headers;

    var range = (header.range || '').match(/=(\d+)-(\d+)?/),
        response = this.response;

    return  new Promise(function (resolve, reject) {

        FS.createReadStream(
            file_path,
            (! range)  ?  { }  :  {
                start:  range[0],    end:  range[1]
            }
        ).once('error', reject).pipe(
            response.once('pipe',  function () {

                this.setHeader(
                    'Content-Type',
                    MINE_Type( file_path )  ||  header.accept.split(',')[0]
                );

                if (! range)  return;

                this.statusCode = 206;

                this.setHeader(
                    'Content-Range',  `bytes ${range[0]}-${range[1] || ''}`
                );
            }).once('end', resolve).once('error', reject)
        );
    });
};
